home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet multimedia
/
Muzyka
/
Edytory sampli (probek dzwieku)
/
ZynAddSubFX_2.2.0
/
Setup_ZynAddSubFX-2.2.0.exe
/
source code
/
Effects
/
Alienwah.C
next >
Wrap
C/C++ Source or Header
|
2005-03-14
|
6KB
|
245 lines
/*
ZynAddSubFX - a software synthesizer
Alienwah.C - "AlienWah" effect
Copyright (C) 2002-2005 Nasca Octavian Paul
Author: Nasca Octavian Paul
This program is free software; you can redistribute it and/or modify
it under the terms of version 2 of the GNU General Public License
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License (version 2) for more details.
You should have received a copy of the GNU General Public License (version 2)
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <math.h>
#include "Alienwah.h"
#include <stdio.h>
Alienwah::Alienwah(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_){
efxoutl=efxoutl_;
efxoutr=efxoutr_;
oldl=NULL;
oldr=NULL;
filterpars=NULL;
insertion=insertion_;
Ppreset=0;
setpreset(Ppreset);
cleanup();
oldclfol.a=fb;oldclfol.b=0.0;
oldclfor.a=fb;oldclfor.b=0.0;
};
Alienwah::~Alienwah(){
if (oldl!=NULL) delete [] oldl;
if (oldr!=NULL) delete [] oldr ;
};
/*
* Apply the effect
*/
void Alienwah::out(REALTYPE *smpsl,REALTYPE *smpsr){
int i;
REALTYPE lfol,lfor;
COMPLEXTYPE clfol,clfor,out,tmp;
lfo.effectlfoout(&lfol,&lfor);
lfol*=depth*PI*2.0;lfor*=depth*PI*2.0;
clfol.a=cos(lfol+phase)*fb;clfol.b=sin(lfol+phase)*fb;
clfor.a=cos(lfor+phase)*fb;clfor.b=sin(lfor+phase)*fb;
for (i=0;i<SOUND_BUFFER_SIZE;i++){
REALTYPE x=((REALTYPE) i)/SOUND_BUFFER_SIZE;
REALTYPE x1=1.0-x;
//left
tmp.a=clfol.a*x+oldclfol.a*x1;
tmp.b=clfol.b*x+oldclfol.b*x1;
out.a=tmp.a*oldl[oldk].a-tmp.b*oldl[oldk].b
+(1-fabs(fb))*smpsl[i]*panning;
out.b=tmp.a*oldl[oldk].b+tmp.b*oldl[oldk].a;
oldl[oldk].a=out.a;
oldl[oldk].b=out.b;
REALTYPE l=out.a*10.0*(fb+0.1);
//right
tmp.a=clfor.a*x+oldclfor.a*x1;
tmp.b=clfor.b*x+oldclfor.b*x1;
out.a=tmp.a*oldr[oldk].a-tmp.b*oldr[oldk].b
+(1-fabs(fb))*smpsr[i]*(1.0-panning);
out.b=tmp.a*oldr[oldk].b+tmp.b*oldr[oldk].a;
oldr[oldk].a=out.a;
oldr[oldk].b=out.b;
REALTYPE r=out.a*10.0*(fb+0.1);
if (++oldk>=Pdelay) oldk=0;
//LRcross
efxoutl[i]=l*(1.0-lrcross)+r*lrcross;
efxoutr[i]=r*(1.0-lrcross)+l*lrcross;
};
oldclfol.a=clfol.a;oldclfol.b=clfol.b;
oldclfor.a=clfor.a;oldclfor.b=clfor.b;
};
/*
* Cleanup the effect
*/
void Alienwah::cleanup(){
for (int i=0;i<Pdelay;i++) {
oldl[i].a=0.0;
oldl[i].b=0.0;
oldr[i].a=0.0;
oldr[i].b=0.0;
};
oldk=0;
};
/*
* Parameter control
*/
void Alienwah::setdepth(unsigned char Pdepth){
this->Pdepth=Pdepth;
depth=(Pdepth/127.0);
};
void Alienwah::setfb(unsigned char Pfb){
this->Pfb=Pfb;
fb=fabs((Pfb-64.0)/64.1);
fb=sqrt(fb);
if (fb<0.4) fb=0.4;
if (Pfb<64) fb=-fb;
};
void Alienwah::setvolume(unsigned char Pvolume){
this->Pvolume=Pvolume;
outvolume=Pvolume/127.0;
if (insertion==0) volume=1.0;
else volume=outvolume;
};
void Alienwah::setpanning(unsigned char Ppanning){
this->Ppanning=Ppanning;
panning=Ppanning/127.0;
};
void Alienwah::setlrcross(unsigned char Plrcross){
this->Plrcross=Plrcross;
lrcross=Plrcross/127.0;
};
void Alienwah::setphase(unsigned char Pphase){
this->Pphase=Pphase;
phase=(Pphase-64.0)/64.0*PI;
};
void Alienwah::setdelay(unsigned char Pdelay){
if (oldl!=NULL) delete [] oldl;
if (oldr!=NULL) delete [] oldr;
if (Pdelay>=MAX_ALIENWAH_DELAY) Pdelay=MAX_ALIENWAH_DELAY;
this->Pdelay=Pdelay;
oldl=new COMPLEXTYPE[Pdelay];
oldr=new COMPLEXTYPE[Pdelay];
cleanup();
};
void Alienwah::setpreset(unsigned char npreset){
const int PRESET_SIZE=11;
const int NUM_PRESETS=4;
unsigned char presets[NUM_PRESETS][PRESET_SIZE]={
//AlienWah1
{127,64,70,0,0,62,60,105,25,0,64},
//AlienWah2
{127,64,73,106,0,101,60,105,17,0,64},
//AlienWah3
{127,64,63,0,1,100,112,105,31,0,42},
//AlienWah4
{93,64,25,0,1,66,101,11,47,0,86}};
if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1;
for (int n=0;n<PRESET_SIZE;n++) changepar(n,presets[npreset][n]);
if (insertion==0) changepar(0,presets[npreset][0]/2);//lower the volume if this is system effect
Ppreset=npreset;
};
void Alienwah::changepar(int npar,unsigned char value){
switch(npar){
case 0: setvolume(value);
break;
case 1: setpanning(value);
break;
case 2: lfo.Pfreq=value;
lfo.updateparams();
break;
case 3: lfo.Prandomness=value;
lfo.updateparams();
break;
case 4: lfo.PLFOtype=value;
lfo.updateparams();
break;
case 5: lfo.Pstereo=value;
lfo.updateparams();
break;
case 6: setdepth(value);
break;
case 7: setfb(value);
break;
case 8: setdelay(value);
break;
case 9: setlrcross(value);
break;
case 10:setphase(value);
break;
};
};
unsigned char Alienwah::getpar(int npar){
switch (npar){
case 0: return(Pvolume);
break;
case 1: return(Ppanning);
break;
case 2: return(lfo.Pfreq);
break;
case 3: return(lfo.Prandomness);
break;
case 4: return(lfo.PLFOtype);
break;
case 5: return(lfo.Pstereo);
break;
case 6: return(Pdepth);
break;
case 7: return(Pfb);
break;
case 8: return(Pdelay);
break;
case 9: return(Plrcross);
break;
case 10:return(Pphase);
break;
default:return (0);
};
};